//
//  CalendarView.swift
//  FastDevelop
//
//  Created by IOS1 on 2025/6/27.
//

import UIKit

class CalendarView: UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    private let calendar = Calendar.current
    private var currentDate = Date()
    private var selectedMonthDate = Date()
    private var daysInMonth: [Date] = []

    private let headerLabel = UILabel()
    private let collectionView: UICollectionView
    
    private var selectedDate: Date? = Date()

    var updateDataBlock: ((_: String) -> Void)?

    override init(frame: CGRect) {
        
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 4

        collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        super.init(frame: frame)

        setupHeader()
        reloadCalendar()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupHeader() {
        
        let previousButton = UIButton(type: .system)
        previousButton.setImage(UIImage(named: "note_left"), for: .normal)
        previousButton.addTarget(self, action: #selector(previousMonth), for: .touchUpInside)

        let nextButton = UIButton(type: .system)
        nextButton.setImage(UIImage(named: "note_right"), for: .normal)
        nextButton.addTarget(self, action: #selector(nextMonth), for: .touchUpInside)

        headerLabel.font = .boldSystemFont(ofSize: 18)

        let headerStack = UIView()
        headerStack.addSubviews([
            previousButton,
            nextButton,
            headerLabel
        ])
        headerLabel.snp.makeConstraints { make in
            make.leading.top.equalToSuperview()
        }
        nextButton.snp.makeConstraints { make in
            make.trailing.equalToSuperview()
            make.width.height.equalTo(24)
            make.centerY.equalTo(headerLabel)
        }
        previousButton.snp.makeConstraints { make in
            make.trailing.equalTo(nextButton.snp.leading).offset(-24)
            make.width.height.equalTo(24)
            make.centerY.equalTo(headerLabel)
        }

        let weekdayStack = UIStackView()
        weekdayStack.axis = .horizontal
        weekdayStack.distribution = .fillEqually
        weekdayStack.spacing = 0

        let weekdays = calendar.shortWeekdaySymbols // ["Sun", "Mon", ..., "Sat"]
        for day in weekdays {
            let label = UILabel()
            label.text = day
            label.textAlignment = .center
            label.font = .systemFont(ofSize: 13, weight: .medium)
            label.textColor = UIColor(hexString: "#3C3C43",alpha: 0.3)
            weekdayStack.addArrangedSubview(label)
        }

        let stack = UIView()
        stack.addSubviews([
            headerStack,
            weekdayStack
        ])
        headerStack.snp.makeConstraints { make in
            make.leading.trailing.top.equalToSuperview()
            make.height.equalTo(35)
        }
        weekdayStack.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview()
            make.height.equalTo(20)
            make.top.equalTo(headerStack.snp.bottom)
        }

        addSubview(stack)
        stack.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(30)
            make.trailing.equalToSuperview().offset(-30)
            make.top.equalToSuperview().offset(5)
            make.height.equalTo(55)
        }
        
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.register(CalendarCell.self, forCellWithReuseIdentifier: "cell")
        collectionView.backgroundColor = .clear

        addSubview(collectionView)
        collectionView.translatesAutoresizingMaskIntoConstraints = false

        let h = (CGFloat.screenWidth/7.0)*5
        collectionView.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(30)
            make.trailing.equalToSuperview().offset(-30)
            make.top.equalTo(stack.snp.bottom)
            make.height.equalTo(h)
        }
    }

    private func reloadCalendar() {
        daysInMonth = []

        let components = calendar.dateComponents([.year, .month], from: selectedMonthDate)
        selectedMonthDate = calendar.date(from: components)!
        let range = calendar.range(of: .day, in: .month, for: selectedMonthDate)!
        let firstOfMonth = selectedMonthDate

        let weekday = calendar.component(.weekday, from: firstOfMonth)
        let numPrefixDays = ((weekday - calendar.firstWeekday) + 7) % 7

        if numPrefixDays > 0,
           let prevMonth = calendar.date(byAdding: .month, value: -1, to: selectedMonthDate),
           let prevRange = calendar.range(of: .day, in: .month, for: prevMonth) {

            let prefixDays = prevRange.count - numPrefixDays + 1
            for day in prefixDays...prevRange.count {
                if let date = calendar.date(bySetting: .day, value: day, of: prevMonth) {
                    daysInMonth.append(date)
                }
            }
        }

        // Add current month days
        for day in range {
            if let date = calendar.date(bySetting: .day, value: day, of: selectedMonthDate) {
                daysInMonth.append(date)
            }
        }

        // Add suffix days from next month
        while daysInMonth.count % 7 != 0 {
            if let nextMonth = calendar.date(byAdding: .month, value: 1, to: selectedMonthDate),
               let date = calendar.date(bySetting: .day, value: daysInMonth.count - range.count - numPrefixDays + 1, of: nextMonth) {
                daysInMonth.append(date)
            }
        }

        let formatter = DateFormatter()
        formatter.dateFormat = "MMMM yyyy"
        formatter.locale = Locale(identifier: "en_US")
        headerLabel.text = formatter.string(from: selectedMonthDate)

        collectionView.reloadData()
    }

    @objc private func previousMonth() {
        selectedMonthDate = calendar.date(byAdding: .month, value: -1, to: selectedMonthDate)!
        reloadCalendar()
    }

    @objc private func nextMonth() {
        selectedMonthDate = calendar.date(byAdding: .month, value: 1, to: selectedMonthDate)!
        reloadCalendar()
    }

    // MARK: - CollectionView DataSource

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return daysInMonth.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? CalendarCell else {
            return UICollectionViewCell()
        }

        let date = daysInMonth[indexPath.item]
        let day = calendar.component(.day, from: date)
        cell.label.text = "\(day)"

        let inMonth = calendar.isDate(date, equalTo: selectedMonthDate, toGranularity: .month)
        cell.label.textColor = inMonth ? .black : .lightGray

        if let selected = selectedDate, calendar.isDate(date, inSameDayAs: selected) {
            cell.backgroundColor = .systemBlue.withAlphaComponent(0.15)
            cell.label.textColor = .white
            cell.layer.cornerRadius = 6
        } else {
            cell.backgroundColor = .clear
        }


        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = collectionView.bounds.width / 7
        return CGSize(width: width, height: width * 0.9)
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let date = daysInMonth[indexPath.item]
        selectedDate = date
        collectionView.reloadData()
        
        let chooseDate = date.formattedCalendarDate()
        updateDataBlock?(chooseDate)
    }

}



class CalendarCell: UICollectionViewCell {
    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)

        label.textAlignment = .center
        label.font = .systemFont(ofSize: 15)
        contentView.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
            label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            label.widthAnchor.constraint(equalTo: contentView.widthAnchor),
            label.heightAnchor.constraint(equalTo: contentView.heightAnchor)
        ])
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

